<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

		<title>云函数Faas概述</title>

		<link rel="stylesheet" href="dist/reset.css">
		<link rel="stylesheet" href="dist/reveal.css">
		<link rel="stylesheet" href="dist/theme/black.css" id="theme">

		<!-- Theme used for syntax highlighted code -->
		<link rel="stylesheet" href="plugin/highlight/monokai.css" id="highlight-theme">
	</head>
	<body>
		<div class="reveal">
			<div class="slides">
				<section>
					<h3 style="margin-top: 100px;">云函数Faas概述</h3>
					<p style="margin-top: 100px;">
						<small>Created by <a href="https://gitee.com/iamllitog" target="_blank">李桐</a></small>
					</p>
					<img style="width: 140px;position: relative; top: -50px;" src="assets/travelsky.png" alt="">
				</section>
				<section>
					<section>
						<h2>相关概念</h2>
					</section>
					<section>
						<h2>1.无服务器</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">无服务器并不是没有服务器就能够进行计算，而是对于开发者来说，无需了解底层的服务器情况，也能使用到相关资源，因此称为无服务器。</li>
						</ul>
						<img class="fragment" src="assets/serverless.jpg" alt="">
					</section>
					<section>
						<h2>2.函数即服务(Faas)</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">函数即服务提供了一种直接在云上运行无状态的、短暂的、由事件触发的代码的能力。</li>
							<li style="font-size: 25px;" class="fragment">函数即服务和传统应用架构不同，函数服务提供的是事件触发式的运行方式，云函数不是始终运行的状态，而是在事件发生时由事件触发运行，并且在一次运行的过程中处理这一次事件。因此在云函数的代码中，仅需考虑针对一个事件的处理流程，而针对大量事件的高并发处理，由平台实现云函数的多实例并发来支持。</li>
							<li style="font-size: 25px;" class="fragment">为了实现对高并发的支持，云函数平台提供了自动的弹性伸缩能力，会在有大量请求到来时启动更多实例来处理事件请求，也会在没有事件到来时缩减函数实例甚至到零实例。因此为了匹配自动扩缩能力，需要函数代码使用的是无状态开发方式，即不在云函数的运行内存中保留相关的状态数据并在多次运行时依赖这些状态数据。云函数的状态数据，可以依赖外部的持久存储能力例如云缓存、云数据库、云存储来进行。</li>
						</ul>
					</section>
					<section>
						<h2>3.触发器</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">任何可以产生事件，触发云函数执行的均可以被称为触发器或触发源。触发器在本身产生事件后，通过将事件传递给云函数来触发函数运行。</li>
							<li style="font-size: 25px;" class="fragment">触发器在触发函数时，可以根据自身特点，使用同步或异步方式触发函数。同步方式触发函数时，触发器将等待函数执行完成并获取到函数执行结果；异步方式触发函数时，触发器将仅触发函数而忽略函数执行结果。</li>
							<li style="font-size: 25px;" class="fragment">常见的触发器有定时器、api网关、函数间调用等等</li>
						</ul>
					</section>
					<section>
						<h2>4.事件</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">触发器在触发函数时会将事件传递给云函数。事件在传递时以一个特定的数据结构体现，数据结构格式在传递时均为 JSON 格式，并以函数 event 入参的方式传递给云函数。</li>
							<li style="font-size: 25px;" class="fragment">触发事件的 JSON 数据内容，在不同的语言环境下将会转换为各自语言的数据结构或对象，无需在代码中自行进行从 JSON 结构到数据结构的转换。</li>
							<li style="font-size: 25px;" class="fragment">例如，在 Python 环境中，JSON 数据内容会转变为一个复杂 dict 对象，即函数的入参 event 就是一个 Python 的复杂 dict 对象。而在 Golang 或 Java 中，入参是一个需要和 event 数据结构可以匹配的对象。</li>
						</ul>
					</section>
				</section>
				<section>
					<section>
						<h2>工作原理</h2>
					</section>
					<section>
						<h2>函数运行时的容器模型</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">云函数将在事件触发时代表您执行云函数，根据您的配置信息（如内存大小等）进行资源分配，并启动和管理容器（即函数的执行环境）。云函数平台负责所有函数运行容器的创建、管理和删除清理操作，用户没有权限对其进行管理。</li>
							<li style="font-size: 25px;" class="fragment">容器启动需要一些时间，这会使每次调用函数时增加一些延迟。但通常仅在首次调用函数、更新函数或长时间未调用时重新调用函数时才会察觉到延迟。因为平台为了尽量减少容器启动延迟，会尝试对后续调用重用容器，在调用函数后容器会根据平台的实际情况存留一段时间，预期用于下次调用，在此时间段内的调用会直接重用该容器。</li>
						</ul>
					</section>
					<section>
						<h2>容器重用机制的意义</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment">用户代码中位于 执行方法 外部的任何声明保持已初始化的状态，再次调用函数时可以直接重用。例如，如果您的函数代码中建立了数据库连接，容器重用时可以直接使用原始连接。您可以在代码中添加逻辑，在创建新连接之前检查是否已存在连接。</li>
							<li style="font-size: 25px;" class="fragment">每个容器在 /tmp 目录中提供部分磁盘空间。容器存留时该目录内容会保留，提供可用于多次调用的暂时性缓存。再次调用函数时有可能可以直接使用该磁盘内容，您可以添加额外的代码来检查缓存中是否有您存储的数据。</li>
						</ul>
					</section>
				</section>
				<section>
					<section>
						<h2>优势</h2>
					</section>
					<section>
						<h2>1.简单易用</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>减少组件开销:</strong>使用云函数时，用户只需编写最重要的 “核心代码”，不再需要关心负载均衡、自动伸缩、网关等周边组件，极大地降低了服务架构搭建的复杂性。</li>
							<li style="font-size: 25px;" class="fragment"><strong>自动扩缩容:</strong>无需任何手动配置，云函数即可根据请求量自动横向扩缩。不管您的应用每天只有几个请求（如日志统计等定期事务），还是每秒有几千上万个请求（如移动应用的后端），云函数均可自动安排合理的计算资源满足业务需求。</li>
						</ul>
						<img class="fragment" src="assets/runtime.jpg" alt="">
					</section>
					<section>
						<h2>2.高效又创造性地开发</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>加速开发:</strong>云函数不要求特定框架或依赖，开发者可以专注于核心代码的开发。同时开发人员可以组成多个小团队，单个模块的开发无需了解其他团队的代码细节。独立开发和迭代的速度变得前所未有的快，帮助用户把握住产品上线的黄金时间。</li>
							<li style="font-size: 25px;" class="fragment"><strong>复用第三方服务:</strong>您可以使用云函数编写一些目的单一、逻辑独立的业务模块，因而可以完全复用已经成熟的第三方代码实现，例如使用 OAuth 实现登录模块。</li>
							<li style="font-size: 25px;" class="fragment"><strong>简化运维:</strong>每个函数都是单独运行、单独部署、单独伸缩的，用户上传代码后即可自动部署，免除单体式应用部署升级难的问题。</li>
						</ul>
					</section>
					<section>
						<h2>3.稳定可靠</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>高可用部署:</strong>云函数可以自动在每个地域中随机地选择可用区来运行。如果某个可用区因灾害或电力故障等导致瘫痪，云函数会自动地选择其他可用区的基础设施来运行，免除单可用区运行的故障风险。</li>
							<li style="font-size: 25px;" class="fragment"><strong>与已有项目结合不冲突:</strong>您可以使用云函数编写一些目的单一、逻辑独立的业务模块。与已有模块互不影响，不同的业务使用不同实现方式，使您的服务架构更加健壮。</li>
						</ul>
					</section>
					<section>
						<h2>4.简化管理</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>简化安全配置:</strong>用户不再需要对 OS 入侵、登录风险、文件系统安全、网络安全和端口监听做复杂的配置和管理，一切交由平台处理，平台通过定制化的容器保证每个用户的隔离性。</li>
							<li style="font-size: 25px;" class="fragment"><strong>可视化管理:</strong>用户可直接在控制台管理函数代码及函数何时运行（即函数触发器），无需复杂的配置文件即可一键部署和测试函数</li>
						</ul>
						<img style="height: 400px;" class="fragment" src="assets/dashboard.png" alt="">
					</section>
					<section>
						<h2>5.大幅度降低开销
						</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>永远不为空闲时间付费:</strong>函数在未执行时不产生任何费用，对一些并非常驻的业务进程来说开销将大大降低。函数执行时按请求数和计算资源的运行时间收费，价格优势明显，对初创期的开发者十分友好。</li>
						</ul>
						<img class="fragment" src="assets/moneyinfo.png" alt="">
					</section>
				</section>
				<section>
					<section>
						<h2>开发工具</h2>
					</section>
					<section>
						<img style="width: 30vw;" src="assets/serverless-logo.svg" alt="">
						<!-- <h2>1.Serverless概述</h2> -->
						<p style="font-size: 30px;">Serverless Framework 是业界非常受欢迎的无服务器应用框架，开发者无需关心底层资源即可部署完整可用的 Serverless 应用架构</p>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>减少组件开销:</strong>使用云函数时，用户只需编写最重要的 “核心代码”，不再需要关心负载均衡、自动伸缩、网关等周边组件，极大地降低了服务架构搭建的复杂性。</li>
							<li style="font-size: 25px;" class="fragment"><strong>自动扩缩容:</strong>无需任何手动配置，云函数即可根据请求量自动横向扩缩。不管您的应用每天只有几个请求（如日志统计等定期事务），还是每秒有几千上万个请求（如移动应用的后端），云函数均可自动安排合理的计算资源满足业务需求。</li>
						</ul>
					</section>
					<section data-auto-animate>
						<h2 data-id="code-title">2.安装Serverless</h2>
						<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
							npm install -g serverless 	// 安装
							npm update -g serverless 	// 升级
							serverless -v 			// 查看版本
						</code></pre>
					</section>
					<section data-auto-animate>
						<h2 data-id="code-title">2.安装Serverless</h2>
						<pre data-id="code-animation"><code class="hljs" data-trim data-line-numbers>
							cnpm install -g serverless 	// 安装
							cnpm update -g serverless 	// 升级
							serverless -v 			// 查看版本
						</code></pre>
					</section>
				</section>
				<section>
					<section>
						<h2>开发示例</h2>
					</section>
					<section>
						<h2>需求梳理:可转债三线查询</h2>
						<p style="font-size: 30px;" class="fragment">可转债是一种混合证券，是公司的一种债券，他可以按照公式转换成公司的股票。既保留了债券性质，又保留了股权性质。</p>
						<img class="fragment" src="assets/convertible.jpeg" alt="">
					</section>
					<section>
						<h2>可转债的赎回情况</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>赎回：</strong>可转债的赎回指如果当前可转债价格连续三十个交易日中至少有十五个交易日的收盘价不低于当期转股价格的130%，则上市公司有权按照债券面值加当期应计利息的价格赎回全部或部分未转股的可转换公司债券。</li>
							<li style="font-size: 25px;" class="fragment"><strong>意义：</strong>低成本融资，当你的可转债价格持续高的时候，公司就要支付比较多的利息给债券持有人，违背了低沉本融资的初衷，但是当持有人转股，就变成股东，上市公司就不用还债，而且强制赎回后，剩余期限的利息也不用付了。</li>
							<li style="font-size: 25px;" class="fragment"><strong>操作：</strong>使用可转债估值工具（评级机构获取），选择价位较低评级较好的可转债建立三线投资，在130元以上并在未触发赎回前卖出。</li>
							<li style="font-size: 25px;" class="fragment"><strong>收益：</strong>三年30%左右，远高于市场上其他稳健类收益。</li>
						</ul>
					</section>
					<section>
						<h2>具体需求</h2>
						<p style="font-size: 25px;" class="fragment">现有市面上所有可转债评级数据和可转债了建仓、加仓、重仓价格数据（锚点文件）；</p>
						<p style="font-size: 25px;" class="fragment">需要根据该数据和当前可转债价格，为市面上所有可转债根据建仓、加仓、重仓划分表格；并按照评级排序；</p>
						<img class="fragment" src="assets/example1.png" alt="">
					</section>
					<section>
						<h2>函数列表</h2>
						<ul>
							<li style="font-size: 25px;" class="fragment"><strong>前端展示：</strong>a.vue环境；b.反向代理；c.处理数据；d.读取当前可转债信息；e.上传锚点文件入口</li>
							<li style="font-size: 25px;" class="fragment"><strong>获取可转债当前价格：</strong>a.在交易日每隔半小时触发一次；b.写入数据库</li>
							<li style="font-size: 25px;" class="fragment"><strong>上传锚点文件：</strong>a.解析锚点文件数据；b.按照要求存入数据库</li>
							<li style="font-size: 25px;" class="fragment"><strong>获取前端数据：</strong>a.根据重仓、加仓、建仓分为三个表格；b.根据评级排序</li>
						</ul>
					</section>
				</section>
				<section>
					<section>
						<h2>开发</h2>
					</section>
					<section>
						<h2>1.开发流程</h2>
						<img src="assets/开发流程.png" alt="">
					</section>
					<section>
						<ol>
							<li style="font-size: 25px;"><strong>准备工作：</strong>包含 注册腾讯云账号、开通云函数服务、配置基本开发环境等。</li>
							<li style="font-size: 25px;" class="fragment"><strong>编写函数：</strong>函数是调度与运行的基本单元，编写函数时需遵循函数接口规范。</li>
							<li style="font-size: 25px;" class="fragment"><strong>本地测试：</strong>可在本地进行代码调试，并将代码部署到云端。</li>
							<li style="font-size: 25px;" class="fragment"><strong>部署函数（含配置触发器）：</strong>代码部署到云端后，云函数可在配置好条件后执行函数。函数的执行条件被称为触发器，您可以配置定时、API 网关、COS 等多种触发器。</li>
							<li style="font-size: 25px;" class="fragment"><strong>云端测试：</strong>函数在云端部署完成后，可通过已配置的触发方式测试云函数。</li>
							<li style="font-size: 25px;" class="fragment"><strong>查看日志：</strong>云函数支持以多种方式查看历史或实时的函数日志。</li>
							<li style="font-size: 25px;" class="fragment"><strong>查看监控：</strong>可通过查看监控指标，了解函数运行的状况。</li>
							<li style="font-size: 25px;" class="fragment"><strong>配置告警：</strong>对于线上生产业务非常关键。在配置告警后，当业务出现异常情况，您可以及时收到告警信息。</li>
						</ol>
					</section>
				</section>
				<section>
					<section>
						<h2>编写函数</h2>
						<img src="assets/code.png" alt="">
					</section>
					<section>
						<h2>编写配置文件</h2>
						<img style="margin-top: -20px;" src="assets/config.png" alt="">
						<p style="margin-top: -20px;font-size: 25px;" class="fragment"><a href="https://github.com/serverless-components/tencent-express/blob/master/docs/configure.md" target="_blank">具体配置</a></p>
					</section>
					<section>
						<h2>发布</h2>
						<pre data-id="code-animation" class="fragment"><code class="hljs" data-trim data-line-numbers>
							serverless deploy
						</code></pre>
					</section>
				</section>
				<section>
					<section>
						<h2>其他功能</h2>
					</section>
					<section>
						<h2>1.监控及告警</h2>
						<img src="assets/alert.png" alt="">
					</section>
					<section>
						<h2>2.在线安装node_modules</h2>
						<img src="assets/nodemodules.png" alt="">
					</section>
					<section>
						<h2>3.版本及流量</h2>
						<img src="assets/version1.png" alt="">
						<ul>
							<li style="font-size: 25px;" class="fragment">当您希望任意两个版本按设定的百分比权重进行随机路由时，可进行 <a href="https://cloud.tencent.com/document/product/583/43716#RandomRoutingByWeight" target="_blank">按权重随机路由</a> 操作。</li>
							<li style="font-size: 25px;" class="fragment">当您想将包含有某个特定内容的请求路由到某一个版本时，可进行 <a href="https://cloud.tencent.com/document/product/583/43716#RandomRoutingByWeight" target="_blank">按规则路由</a> 操作。</li>
						</ul>
					</section>
					<section>
						<h2>4.更多</h2>
						<ul>
							<li style="font-size: 25px;">灰度发布</li>
							<li style="font-size: 25px;">权限管理</li>
							<li style="font-size: 25px;">网络配置</li>
							<li style="font-size: 25px;">层管理</li>
							<li style="font-size: 25px;">日志</li>
							<li style="font-size: 25px;">...</li>
						</ul>
					</section>
				</section>
				<section>
					<h1>感谢观看</h1>
					<p><a href="https://gitee.com/iamllitog/convertible" target="_blank">项目代码</a>&<a href="https://gitee.com/iamllitog/FaasPpt" target="_blank">PPT</a></p>
				</section>
			</div>
		</div>

		<script src="dist/reveal.js"></script>
		<script src="plugin/notes/notes.js"></script>
		<script src="plugin/markdown/markdown.js"></script>
		<script src="plugin/highlight/highlight.js"></script>
		<script>
			// More info about initialization & config:
			// - https://revealjs.com/initialization/
			// - https://revealjs.com/config/
			Reveal.initialize({
				hash: true,
				transition: 'convex',

				// Learn about plugins: https://revealjs.com/plugins/
				plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ]
			});
		</script>
	</body>
</html>
